package com.yitao.cms.service.product;

import com.skipper.base.bean.CommonStatus;
import com.skipper.base.bean.DataOutput;
import com.skipper.base.data.querydsl.PredicateBuilder;
import com.skipper.base.service.GenericEntityService;
import com.yitao.client.constant.BaseConstant;
import com.yitao.client.constant.ProductConstant;
import com.yitao.client.dto.product.ProductImgDto;
import com.yitao.client.dto.product.ProductSkuDto;
import com.yitao.client.dto.product.ProductStockDto;
import com.yitao.client.model.product.*;
import com.yitao.cms.constant.UserErrorEnum;
import com.yitao.cms.constant.UserSession;
import com.yitao.cms.dto.product.ProductParentAttrSpec;
import com.yitao.cms.dto.product.ProductSkuAddDto;
import com.yitao.cms.dto.product.ProductSkuUpdateDto;
import com.yitao.cms.model.operationUser.OperationUserCmsModel;
import com.yitao.cms.utils.BaseUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author:Wwl
 * @Description:
 * @Date:17:07 2019/3/9
 */

@Service
public class ProductCmsSkuService extends GenericEntityService<ProductSkuModel, ProductSkuDto, QProductSkuModel> {
    public ProductCmsSkuService(EntityManager entityManager) {
        super(entityManager);
    }

    @Autowired
    private ProductCmsService productCmsService;
    @Autowired
    private ProductImgService productImgService;
    @Autowired
    private ProductCmsStockService productCmsStockService;

    private BaseUtils base = BaseUtils.getInstance();

    /**
     * 根据父级skuCode 构建子sku
     *
     * @param parentSkuCode
     * @return
     */
    private String getSkuCodeByProductCode(String parentSkuCode, int i) {
        //TODO 单级别 SKU 默认为 code+00+序号
        return parentSkuCode + "00" + String.valueOf(i);
    }

    /**
     * 批量添加sku信息
     *
     * @param request
     * @param productSkuAddDto
     * @return
     */
    @Transactional
    public DataOutput saveProductSKU(HttpServletRequest request, ProductSkuAddDto productSkuAddDto) {
        //验证登陆信息
        OperationUserCmsModel userSession = UserSession.getUserSession(request);
        if (userSession == null) {
            return new DataOutput(UserErrorEnum.NULL_LOGIN.getCode(), UserErrorEnum.NULL_LOGIN.getDesc());
        }
        if (productSkuAddDto == null) {
            return base.getBadErrorMsg("传递参数有误!");
        }
        logger.info("添加sku信息:{}",productSkuAddDto);
        //一级与二级规格名不重复
        if (productSkuAddDto.getParentAttrSpecName().equals(productSkuAddDto.getAttrSpecName())) {
            return base.getBadErrorMsg("一级规格名:" + productSkuAddDto.getParentAttrSpecName() + "与二级规格名:" + productSkuAddDto.getAttrSpecName() + "重复!");
        }
        //一级规格值之间不重复
        if (!CollectionUtils.isEmpty(productSkuAddDto.getParentAttrSpecList())) {
            List<String> listAttrSpecName = new ArrayList<>();
            for (ProductParentAttrSpec productParentAttrSpec : productSkuAddDto.getParentAttrSpecList()) {
                if (listAttrSpecName.contains(productParentAttrSpec.getParentAttrSpecValue())) {
                    return base.getBadErrorMsg("一级规格值:" + productParentAttrSpec.getParentAttrSpecValue() + "重复!");
                } else {
                    listAttrSpecName.add(productParentAttrSpec.getParentAttrSpecValue());
                }
            }
        }
        //二级规格值之间不重复
        if (!CollectionUtils.isEmpty(productSkuAddDto.getAttrSpecValueList())) {
            List<String> listAttrSpecName = new ArrayList<>();
            for (String attrSpec : productSkuAddDto.getAttrSpecValueList()) {
                if (listAttrSpecName.contains(attrSpec)) {
                    return base.getBadErrorMsg("二级规格值:" + attrSpec + "重复!");
                } else {
                    listAttrSpecName.add(attrSpec);
                }
            }
        }
        //判断传入的产品ID是否存在
        ProductInfoModel productInfoModel = null;
        if (productSkuAddDto != null && productSkuAddDto.getProductId() != null) {
            productInfoModel = productCmsService.getProductInfoById(productSkuAddDto.getProductId());
            if (productInfoModel == null) {
                return new DataOutput(CommonStatus.BAD_REQUEST.getCode(), "请输入正确的产品ID");
            }
            //删除之前产品规格库存修改为不可用
            repository.updateByWhere(Q.productId.eq(productInfoModel.getId()), it -> it.set(Q.isDelete, true));
           // productCmsStockService.updateProductStockStatus(productInfoModel.getId(), ProductConstant.ProductEnableEnum.NO);
            productImgService.deleteProductSKUImgByProductId(productInfoModel.getId());
        } else {
            return new DataOutput(CommonStatus.BAD_REQUEST);
        }
        //补充基本信息
        productSkuAddDto.setProductCode(productInfoModel.getProductCode());
        productSkuAddDto.setProductName(productInfoModel.getProductName());
        productSkuAddDto.setCreateBy(Long.valueOf(userSession.getId()));
        productSkuAddDto.setCreateTime(base.getNow());
        productSkuAddDto.setLastUpdateBy(Long.valueOf(userSession.getId()));
        productSkuAddDto.setLastUpdateTime(base.getNow());
        productSkuAddDto.setDelete(false);
        productSkuAddDto.setEnable(true);
        productSkuAddDto.setSale(false);
        if (productSkuAddDto != null) {
            if (productSkuAddDto.getParentAttrSpecList() != null && productSkuAddDto.getParentAttrSpecList().size() > 0) {
                //判断一级是否为主sku
             /*   Boolean mainSku = true;
                if (!CollectionUtils.isEmpty(productSkuAddDto.getAttrSpecValueList()) && productSkuAddDto.getAttrSpecValueList().size()>0){
                    mainSku=false;
                }*/
                for (int i = 0; i < productSkuAddDto.getParentAttrSpecList().size(); i++) {//循环插入一级Sku
                    if (!StringUtils.isEmpty(productSkuAddDto.getParentAttrSpecList().get(i).getParentAttrSpecValue())) {//父级标签非空判断
                        ProductSkuModel productSkuModel = new ProductSkuModel();
                        BeanUtils.copyProperties(productSkuAddDto, productSkuModel);
                        productSkuModel.setParentId(0L);//父级sku
                        productSkuModel.setMarkerPrice(0L);
                        productSkuModel.setSalesPrice(0L);
                        productSkuModel.setWholesalePrice(0L);
                        productSkuModel.setEntityStock(0);//库存
                        productSkuModel.setProductSkuCode(BaseUtils.getCodeByCodeHeader(BaseConstant.SKU_CODE_HEADER));
                        productSkuModel.setAttrSpecName(productSkuAddDto.getParentAttrSpecName());//规格名
                        productSkuModel.setAttrSpecValue(productSkuAddDto.getParentAttrSpecList().get(i).getParentAttrSpecValue());//规格值
                        productSkuModel.setIsMainSku(true);//一级sku
                        productSkuModel.setIsSale(true);
                        ProductSkuModel productSkuModel1 = repository.save(productSkuModel);
                        //添加图片
                        if (productSkuModel1 != null && !StringUtils.isEmpty(productSkuAddDto.getParentAttrSpecList().get(i).getParentImageUrl())) {
                            ProductImgDto productImgDto = new ProductImgDto();
                            BeanUtils.copyProperties(productSkuAddDto, productImgDto);
                            //图片
                            productImgDto.setImageUrl(productSkuAddDto.getParentAttrSpecList().get(i).getParentImageUrl());
                            //图片类型
                            productImgDto.setImageType(ProductConstant.ImgTypeEnum.SKU.getCode());
                            productImgDto.setDelete(false);
                            productImgDto.setImageSort(i);
                            productImgDto.setSkuId(productSkuModel1.getId());
                            productImgDto.setSkuCode(productSkuModel1.getProductSkuCode());
                            ProductImgDto productImgDto1 = productImgService.save(productImgDto);
                        }
                        //添加stock信息
                      /*  if (productSkuModel1 != null) {
                            ProductStockModel productStockModel = new ProductStockModel();
                            BeanUtils.copyProperties(productSkuAddDto, productStockModel);
                            productStockModel.setStockType(ProductConstant.ProductStockTypeEnum.PHYSICAL_HOLDING_STOCK.getCode());
                            productStockModel.setSkuId(productSkuModel1.getId());
                            productStockModel.setSkuCode(productSkuModel1.getProductSkuCode());
                            ProductStockModel productStockModel1 = productCmsStockService.save(productStockModel);
                        }*/
                        //对二级sku进行判断
                        if (productSkuAddDto.getAttrSpecValueList() != null && productSkuAddDto.getAttrSpecValueList().size() > 0) {
                            for (int j = 0; j < productSkuAddDto.getAttrSpecValueList().size(); j++) {
                                if (!StringUtils.isEmpty(productSkuAddDto.getAttrSpecValueList().get(j))) {//标签值非空判断
                                    //添加一级数据
                                    ProductSkuModel productSkuModel2 = new ProductSkuModel();
                                    BeanUtils.copyProperties(productSkuAddDto, productSkuModel2);
                                    productSkuModel2.setParentId(productSkuModel1.getId());//父级sku
                                    productSkuModel2.setMarkerPrice(0L);
                                    productSkuModel2.setSalesPrice(0L);
                                    productSkuModel2.setWholesalePrice(0L);
                                    productSkuModel2.setEntityStock(0);
                                    productSkuModel2.setProductSkuCode(getSkuCodeByProductCode(productSkuModel1.getProductSkuCode(), j + 1));
                                    productSkuModel2.setAttrSpecName(productSkuAddDto.getAttrSpecName());//规格名
                                    productSkuModel2.setAttrSpecValue(productSkuAddDto.getAttrSpecValueList().get(j));//规格值
                                    productSkuModel2.setIsMainSku(false);//
                                    productSkuModel2.setIsSale(true);
                                    ProductSkuModel productSkuModel3 = repository.save(productSkuModel2);
                                    //添加stock信息
                                  /*  if (productSkuModel3 != null) {
                                        ProductStockModel productStockModel = new ProductStockModel();
                                        BeanUtils.copyProperties(productSkuAddDto, productStockModel);
                                        productStockModel.setStockType(ProductConstant.ProductStockTypeEnum.PHYSICAL_HOLDING_STOCK.getCode());
                                        productStockModel.setSkuId(productSkuModel3.getId());
                                        productStockModel.setSkuCode(productSkuModel3.getProductSkuCode());
                                        ProductStockModel productStockModel1 = productCmsStockService.save(productStockModel);
                                    }*/
                                }//标签非空判断结束
                            }
                        }
                    }//父级标签非空判断结束
                }
                return new DataOutput(CommonStatus.SUCCESS);
            }

        }
        return new DataOutput(CommonStatus.BAD_REQUEST);
    }

    /**
     * 根据商品id获取sku集合
     *
     * @param productId
     * @return
     */
    public List<ProductSkuDto> getProductSkuListByProductId(Long productId) {
        List<ProductSkuDto> productSkuDtoList = repository.findAll(PredicateBuilder.conjunction()
                .and(() -> Q.productId.eq(productId))
                .and(() -> Q.parentId.in(null, 0))
                .and(() -> Q.isDelete.eq(false))
                .get()).stream().map(it -> {
            ProductSkuDto productSkuDto = new ProductSkuDto();
            BeanUtils.copyProperties(it, productSkuDto);
            ProductStockDto productStockDto = productCmsStockService.findProductStockBySkuId(productSkuDto.getId());
            productSkuDto.setProductStockDto(productStockDto);
            //补充sku图片信息
            ProductImgModel productImgModel = productImgService.findImgBySkuId(it.getId());
            if (productImgModel != null) {
                productSkuDto.setImageUrl(productImgModel.getImageUrl());
            }
            //补充产品销量信息
           /* ProductInfoModel productInfoModel = productInfoService.getProductById(String.valueOf(productId));
            if (productInfoModel != null) {
                productSkuDto.setSalesCount(productInfoModel.getSalesCount());
            }*/
            //查询下级
            List<ProductSkuDto> list = repository.findAll(Q.productId.eq(productId)
                    .and(Q.parentId.eq(it.getId()))).stream().map(it2 -> {
                ProductSkuDto productSkuDto2 = new ProductSkuDto();
                BeanUtils.copyProperties(it2, productSkuDto2);
                ProductStockDto productStockDto2 = productCmsStockService.findProductStockBySkuId(productSkuDto2.getId());
                productSkuDto2.setProductStockDto(productStockDto2);
                //补充sku图片信息
                ProductImgModel productImgModel2 = productImgService.findImgBySkuId(it.getId());
                if (productImgModel2 != null) {
                    productSkuDto2.setImageUrl(productImgModel2.getImageUrl());
                }
                return productSkuDto2;
            }).collect(Collectors.toList());
            //补充到上级里面
            productSkuDto.setProductSkuDtoList(list);
            return productSkuDto;
        }).collect(Collectors.toList());
        return productSkuDtoList;
    }

    /**
     * 修改SKU价格和库存
     *
     * @param skuId
     * @param salesPrice
     * @param stock
     * @return
     */
    @Transactional
    public DataOutput updateProductSalesAndStockById(HttpServletRequest request, Long skuId, Long salesPrice, Integer stock,String productOutsideBarcode) {
        OperationUserCmsModel userSession = UserSession.getUserSession(request);
        if (userSession == null) {
            return new DataOutput(UserErrorEnum.NULL_LOGIN.getCode(), UserErrorEnum.NULL_LOGIN.getDesc());
        }
        logger.info("修改库存信息:skuId,{},salesPrice,{},stock,{}",skuId,salesPrice,stock);
        try {
            if (skuId != null) {
                int result = repository.updateByWhere(Q.id.eq(skuId), it -> it
                        .set(Q.salesPrice, salesPrice)
                        .set(Q.markerPrice, salesPrice)
                        .set(Q.wholesalePrice, salesPrice)
                        .set(Q.entityStock, stock)
                        .set(Q.productOutsideBarcode,productOutsideBarcode)
                        .set(Q.lastUpdateBy, UserSession.getUserIdBySession(request))
                        .set(Q.lastUpdateTime, base.getNow())
                );
                if (result > 0) {
                    return new DataOutput(CommonStatus.SUCCESS);
                }
            }
            return new DataOutput(CommonStatus.BAD_REQUEST);
        } catch (Exception e) {
            logger.error("修改SKU数据失败{}", e.getMessage());
            return new DataOutput(CommonStatus.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    @Transactional
    public void updateProductSku(List<ProductSkuUpdateDto> productSkuUpdateDtoList) {
        for (ProductSkuUpdateDto productSkuUpdateDto : productSkuUpdateDtoList) {
            if (productSkuUpdateDto.getProductSkuId() != null && productSkuUpdateDto.getEntityStock() != null && productSkuUpdateDto.getSalesPrice() != null) {
                repository.updateByWhere(Q.id.eq(productSkuUpdateDto.getProductSkuId()),
                        it -> it.set(Q.salesPrice, productSkuUpdateDto.getSalesPrice())
                                .set(Q.entityStock, productSkuUpdateDto.getEntityStock()));
            }
        }
    }


    /**
     * 批量修改销量及库存
     *
     * @param productId
     * @param salesPrice
     * @param stock
     * @return
     */
    @Transactional
    public DataOutput updateProductSalesAndStockByProductId(HttpServletRequest request, Long productId, Long salesPrice, Integer stock,String productOutsideBarcode) {
        if (productId == null || salesPrice == null || stock == null) {
            return new DataOutput(CommonStatus.BAD_REQUEST.getCode(), "参数不能为空!");
        }
        OperationUserCmsModel userSession = UserSession.getUserSession(request);
        if (userSession == null) {
            return new DataOutput(UserErrorEnum.NULL_LOGIN.getCode(), UserErrorEnum.NULL_LOGIN.getDesc());
        }
        logger.info("批量修改销量及库存:productId,{},salesPrice,{},stock,{}",productId,salesPrice,stock);
        try {
            if (productId != null) {
                int result = repository.updateByWhere(Q.productId.eq(productId), it -> it
                        .set(Q.salesPrice, salesPrice)
                        .set(Q.markerPrice, salesPrice)
                        .set(Q.wholesalePrice, salesPrice)
                        .set(Q.entityStock, stock)
                        .set(Q.productOutsideBarcode,productOutsideBarcode)
                        .set(Q.lastUpdateBy, UserSession.getUserIdBySession(request))
                        .set(Q.lastUpdateTime, base.getNow())
                );
                if (result > 0) {
                    return new DataOutput(CommonStatus.SUCCESS);
                }
            }
            return new DataOutput(CommonStatus.BAD_REQUEST);
        } catch (Exception e) {
            logger.error("修改SKU数据失败{}", e.getMessage());
            return new DataOutput(CommonStatus.SERVER_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     * 根据ID查询Sku详情
     *
     * @param productSkuId
     * @return
     */
    public ProductSkuModel getProductSkuDtoById(Long productSkuId) {
        return queryFactory.select(Q).from(Q).where(Q.id.eq(productSkuId)).fetchOne();
    }


    public Long entityStockCountByProductId(Long productId) {
        try {
            Integer sum = 0;
            if (productId != null && productId != 0L) {
                List<ProductSkuModel> list = repository.findAll(Q.productId.eq(productId)
                        .and(Q.parentId.isNotNull().or(Q.parentId.eq(0L)))
                        .and(Q.isDelete.eq(false))
                        .and(Q.isEnable.eq(true))
                );
                if (list != null && list.size() > 0) {//有两级或以上等级分类
                    for (ProductSkuModel productSkuModel1 : list) {
                        sum += stockCount(0, productSkuModel1);
                    }
                }
            }
            return Long.valueOf(sum);
        } catch (Exception e) {
            logger.error("统计库存失败{}", e.getMessage());
            return 0L;
        }
    }

    /**
     * 便利统计各级库存
     *
     * @param productSkuModel
     * @return
     */
    private final Integer stockCount(Integer sum, ProductSkuModel productSkuModel) {
        if (productSkuModel != null) {
            List<ProductSkuModel> list = repository.findAll(Q.parentId.eq(productSkuModel.getId())
                    .and(Q.isDelete.eq(false))
                    .and(Q.isEnable.eq(true)));
            if (list != null && list.size() > 0) {
                for (ProductSkuModel productSkuModel1 : list) {
                    stockCount(sum, productSkuModel1);
                }
            } else {
                if (productSkuModel.getEntityStock()!=null){
                    sum += productSkuModel.getEntityStock();
                }
            }
        }
        return sum;
    }

    /**
     * 根据id删除SKU信息
     *
     * @param request
     * @param sukId
     * @return
     */
    public DataOutput deleteProductSKUById(HttpServletRequest request, Long sukId) {
        try {
            OperationUserCmsModel userSession = UserSession.getUserSession(request);
            if (userSession == null) {
                return new DataOutput(UserErrorEnum.NULL_LOGIN.getCode(), UserErrorEnum.NULL_LOGIN.getDesc());
            }
            logger.info("删除SKU信息{}",sukId);
            if (sukId != null) {
                int result = repository.updateByWhere(Q.id.eq(sukId), it -> it.set(Q.isDelete, true)
                        .set(Q.lastUpdateBy, Long.valueOf(userSession.getId())));
                if (result > 0) {
                    return new DataOutput(CommonStatus.SUCCESS);
                }
            }
            return new DataOutput(CommonStatus.BAD_REQUEST);
        } catch (Exception e) {
            logger.error("删除SKU信息失败:{}", e.getMessage());
            return new DataOutput(CommonStatus.SERVER_ERROR);
        }
    }

    /**
     * 修改sku上架状态
     *
     * @param productId
     * @param saleType
     * @return
     */
    @Transactional
    public DataOutput updateProductSkuIsSale(Long productId, Boolean saleType) {
        int result = repository.updateByWhere(Q.productId.eq(productId).and(Q.isDelete.eq(false)), it
                -> it.set(Q.isSale, saleType)
        .set(Q.lastUpdateTime,new Date()));
        if (result > 0) {
            return new DataOutput(CommonStatus.SUCCESS);
        }
        return new DataOutput(CommonStatus.BAD_REQUEST);

    }

    /**
     * 批量修改产品上下架状态
     *
     * @param productIds
     * @param saleStatus
     * @return
     */
    @Transactional
    public DataOutput updateProductIdsSkuIsSale(List<Long> productIds, Boolean saleStatus) {
        int result = repository.updateByWhere(Q.productId.in(productIds).and(Q.isDelete.eq(false)), it
                -> it.set(Q.isSale, saleStatus)
                .set(Q.lastUpdateTime, base.getNow()));
        if (result > 0) {
            return new DataOutput(CommonStatus.SUCCESS);
        }
        return new DataOutput(CommonStatus.BAD_REQUEST);

    }

    /**
     * 根据产品id获取最低级sku信息
     *
     * @param productIds
     * @return
     */
    public List<ProductSkuModel> findSubsetProductSkuList(List<Long> productIds) {
        List<ProductSkuModel> productSkuModelParentList = repository.findAll(Q.productId.in(productIds).and(Q.parentId.eq(0L).and(Q.isDelete.eq(false))));//父级
        List<ProductSkuModel> productSkuModelSubsetList = repository.findAll(Q.productId.in(productIds).and(Q.parentId.gt(0L).and(Q.isDelete.eq(false))));//子集
        for (int i = 0; i < productSkuModelParentList.size(); i++) {
            for (int j = 0; j < productSkuModelSubsetList.size(); j++) {
                if (productSkuModelParentList.get(i).getProductId().equals(productSkuModelSubsetList.get(j).getProductId())) {
                    productSkuModelParentList.remove(i);
                    productSkuModelParentList.add(productSkuModelSubsetList.get(j));
                }
            }
        }
        return productSkuModelParentList;
    }

    public ProductSkuModel getProductCmsSku(String skuCode) {
        return queryFactory.select(Q).from(Q).where(Q.productSkuCode.eq(skuCode).and(Q.isDelete.eq(false))).fetchOne();
    }

    /**
     * 查询sku最低价
     * @param productId
     * @return
     */
    public Long getSalePriceMin(Long productId){
        Long salePrice = null;
        try {
            salePrice = queryFactory.select(Q.salesPrice.min()).from(Q).where(Q.productId.eq(productId).and(Q.isDelete.eq(false)).and(Q.salesPrice.gt(0L))).fetchFirst();
            if (salePrice==null){
                salePrice=0L;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return salePrice;
    }
}
